<template>
  <div class="algorithms-view">
    <h1 class="page-title">全同态加密算法原理</h1>
    <p class="page-description">了解不同类型的同态加密算法原理、特性和应用场景。通过交互式示例，直观理解同态加密的工作原理。</p>
    
    <div class="algorithms-container">
      <!-- RSA（乘法同态）部分 -->
      <div class="algorithm-section">
        <div class="algorithm-header" @click="toggleSection('rsa')">
          <h2>RSA（乘法同态）</h2>
          <span class="toggle-icon">{{ sections.rsa ? '▼' : '▶' }}</span>
        </div>
        
        <div class="algorithm-content" v-if="sections.rsa">
          <div class="algorithm-description">
            <p>RSA是一种广泛使用的非对称加密算法，它具有乘法同态的特性。这意味着两个密文相乘后解密，等同于对应明文相乘后再加密。</p>
            
            <div class="math-formula">
              <p>数学表示：</p>
              <div class="formula">E(a) · E(b) ≡ E(a · b) mod N</div>
              <p>其中，E(x)表示对x的加密，N是RSA模数。</p>
            </div>
          </div>
          
          <div class="interactive-demo">
            <h3>交互式示例</h3>
            <div class="demo-inputs">
              <div class="input-group">
                <label for="rsa-a">数值 A</label>
                <input type="number" id="rsa-a" v-model="rsa.a" min="1" max="100" />
              </div>
              
              <div class="input-group">
                <label for="rsa-b">数值 B</label>
                <input type="number" id="rsa-b" v-model="rsa.b" min="1" max="100" />
              </div>
              
              <button class="btn btn-primary" @click="calculateRSA">计算</button>
            </div>
            
            <div class="demo-results" v-if="rsa.calculated">
              <div class="result-row">
                <div class="result-label">明文相乘:</div>
                <div class="result-value">{{ rsa.a }} × {{ rsa.b }} = {{ rsa.plaintextResult }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">加密 A:</div>
                <div class="result-value encrypted">{{ rsa.encryptedA }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">加密 B:</div>
                <div class="result-value encrypted">{{ rsa.encryptedB }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">密文相乘:</div>
                <div class="result-value encrypted">{{ rsa.ciphertextResult }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">解密结果:</div>
                <div class="result-value">{{ rsa.plaintextResult }}</div>
              </div>
              
              <div class="verification-status success">
                ✓ 验证通过：密文计算结果与明文计算结果一致
              </div>
            </div>
          </div>
          
          <div class="algorithm-limitations">
            <h3>局限性</h3>
            <ul>
              <li>仅支持乘法运算，不支持加法</li>
              <li>每次乘法操作都会增加密文大小</li>
              <li>不适合复杂的计算任务</li>
            </ul>
          </div>
        </div>
      </div>
      
      <!-- Paillier（加法同态）部分 -->
      <div class="algorithm-section">
        <div class="algorithm-header" @click="toggleSection('paillier')">
          <h2>Paillier（加法同态）</h2>
          <span class="toggle-icon">{{ sections.paillier ? '▼' : '▶' }}</span>
        </div>
        
        <div class="algorithm-content" v-if="sections.paillier">
          <div class="algorithm-description">
            <p>Paillier加密是一种非对称加密算法，具有加法同态特性。这意味着两个密文相乘后解密，等同于对应明文相加后再加密。</p>
            
            <div class="math-formula">
              <p>数学表示：</p>
              <div class="formula">E(a) · E(b) ≡ E(a + b) mod n²</div>
              <p>其中，E(x)表示对x的加密，n是Paillier模数。</p>
            </div>
          </div>
          
          <div class="key-generation">
            <h3>密钥生成流程</h3>
            <div class="flow-diagram">
              <div class="flow-step">
                <div class="step-number">1</div>
                <div class="step-content">
                  <p>选择两个大素数 p 和 q</p>
                </div>
              </div>
              
              <div class="flow-arrow">→</div>
              
              <div class="flow-step">
                <div class="step-number">2</div>
                <div class="step-content">
                  <p>计算 n = p·q 和 λ = lcm(p-1, q-1)</p>
                </div>
              </div>
              
              <div class="flow-arrow">→</div>
              
              <div class="flow-step">
                <div class="step-number">3</div>
                <div class="step-content">
                  <p>选择随机整数 g，使得 gcd(L(g^λ mod n²), n) = 1</p>
                </div>
              </div>
              
              <div class="flow-arrow">→</div>
              
              <div class="flow-step">
                <div class="step-number">4</div>
                <div class="step-content">
                  <p>公钥：(n, g)，私钥：λ</p>
                </div>
              </div>
            </div>
          </div>
          
          <div class="interactive-demo">
            <h3>密文加法模拟器</h3>
            <div class="demo-inputs">
              <div class="input-group">
                <label for="paillier-a">数值 A</label>
                <input type="number" id="paillier-a" v-model="paillier.a" min="0" max="1000" />
              </div>
              
              <div class="input-group">
                <label for="paillier-b">数值 B</label>
                <input type="number" id="paillier-b" v-model="paillier.b" min="0" max="1000" />
              </div>
              
              <button class="btn btn-primary" @click="calculatePaillier">计算</button>
            </div>
            
            <div class="demo-results" v-if="paillier.calculated">
              <div class="result-row">
                <div class="result-label">明文相加:</div>
                <div class="result-value">{{ paillier.a }} + {{ paillier.b }} = {{ paillier.plaintextResult }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">加密 A:</div>
                <div class="result-value encrypted">{{ paillier.encryptedA }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">加密 B:</div>
                <div class="result-value encrypted">{{ paillier.encryptedB }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">密文相乘:</div>
                <div class="result-value encrypted">{{ paillier.ciphertextResult }}</div>
              </div>
              
              <div class="result-row">
                <div class="result-label">解密结果:</div>
                <div class="result-value">{{ paillier.plaintextResult }}</div>
              </div>
              
              <div class="verification-status success">
                ✓ 验证通过：密文计算结果与明文计算结果一致
              </div>
            </div>
          </div>
          
          <div class="algorithm-applications">
            <h3>应用场景</h3>
            <ul>
              <li>电子投票系统</li>
              <li>隐私保护的统计分析</li>
              <li>安全多方计算</li>
            </ul>
          </div>
        </div>
      </div>
      
      <!-- BGV/CKKS 部分 -->
      <div class="algorithm-section">
        <div class="algorithm-header" @click="toggleSection('bgv_ckks')">
          <h2>BGV/CKKS（全同态加密）</h2>
          <span class="toggle-icon">{{ sections.bgv_ckks ? '▼' : '▶' }}</span>
        </div>
        
        <div class="algorithm-content" v-if="sections.bgv_ckks">
          <div class="algorithm-description">
            <p>BGV和CKKS是现代全同态加密方案，支持在加密数据上进行任意次数的加法和乘法运算。这些方案基于格密码学，使用多项式环上的计算。</p>
            
            <div class="scheme-comparison">
              <div class="scheme-card">
                <h4>BGV 方案</h4>
                <p>适用于整数运算</p>
                <p>精确计算</p>
                <p>基于RLWE问题</p>
              </div>
              
              <div class="scheme-card">
                <h4>CKKS 方案</h4>
                <p>适用于实数运算</p>
                <p>近似计算（有误差）</p>
                <p>支持批处理操作</p>
              </div>
            </div>
          </div>
          
          <div class="parameter-panel">
            <h3>参数调节面板</h3>
            <div class="parameter-controls">
              <div class="parameter-group">
                <label for="poly-degree">多项式阶数</label>
                <select id="poly-degree" v-model="fhe.polyDegree">
                  <option value="1024">1024</option>
                  <option value="2048">2048</option>
                  <option value="4096">4096</option>
                  <option value="8192">8192</option>
                  <option value="16384">16384</option>
                </select>
                <div class="parameter-description">更高的阶数支持更多的乘法深度，但计算开销更大</div>
              </div>
              
              <div class="parameter-group">
                <label for="modulus-bits">模数位数</label>
                <input type="range" id="modulus-bits" v-model="fhe.modulusBits" min="20" max="60" step="5" />
                <div class="range-value">{{ fhe.modulusBits }} 位</div>
                <div class="parameter-description">更大的模数提供更高的精度，但降低安全性</div>
              </div>
              
              <div class="parameter-group">
                <label for="security-level">安全级别</label>
                <select id="security-level" v-model="fhe.securityLevel">
                  <option value="128">128 位</option>
                  <option value="192">192 位</option>
                  <option value="256">256 位</option>
                </select>
                <div class="parameter-description">更高的安全级别需要更大的参数</div>
              </div>
            </div>
          </div>
          
          <div class="error-growth">
            <h3>误差增长可视化</h3>
            <div class="chart-container">
              <canvas ref="errorChart" width="600" height="300"></canvas>
            </div>
            <div class="chart-description">
              <p>图表展示了在执行连续乘法操作时，密文中误差的增长情况。当误差超过一定阈值时，解密结果将不再正确。</p>
              <p>BGV方案通过模数切换技术控制误差增长，而CKKS方案则通过尺度调整来管理误差。</p>
            </div>
          </div>
          
          <div class="algorithm-applications">
            <h3>应用场景</h3>
            <ul>
              <li>机器学习模型的隐私保护训练和推理</li>
              <li>基因组数据分析</li>
              <li>金融数据的隐私计算</li>
              <li>医疗健康数据的安全处理</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch } from 'vue';

// 控制各部分的展开/折叠状态
const sections = reactive({
  rsa: true,
  paillier: false,
  bgv_ckks: false
});

// 切换部分的展开/折叠
function toggleSection(section) {
  sections[section] = !sections[section];
}

// RSA 示例数据
const rsa = reactive({
  a: 7,
  b: 11,
  calculated: false,
  encryptedA: '',
  encryptedB: '',
  plaintextResult: 0,
  ciphertextResult: ''
});

// Paillier 示例数据
const paillier = reactive({
  a: 42,
  b: 57,
  calculated: false,
  encryptedA: '',
  encryptedB: '',
  plaintextResult: 0,
  ciphertextResult: ''
});

// FHE 参数
const fhe = reactive({
  polyDegree: 4096,
  modulusBits: 30,
  securityLevel: 128
});

// 误差图表引用
const errorChart = ref(null);
let chart = null;

// 计算 RSA 示例
function calculateRSA() {
  // 计算明文结果
  rsa.plaintextResult = rsa.a * rsa.b;
  
  // 模拟 RSA 加密
  rsa.encryptedA = `E(${rsa.a}) = 0x${generateFakeEncryption(rsa.a, 'rsa')}`;
  rsa.encryptedB = `E(${rsa.b}) = 0x${generateFakeEncryption(rsa.b, 'rsa')}`;
  
  // 模拟密文相乘结果
  rsa.ciphertextResult = `E(${rsa.a}) · E(${rsa.b}) = 0x${generateFakeEncryption(rsa.plaintextResult, 'rsa')}`;
  
  rsa.calculated = true;
}

// 计算 Paillier 示例
function calculatePaillier() {
  // 计算明文结果
  paillier.plaintextResult = paillier.a + paillier.b;
  
  // 模拟 Paillier 加密
  paillier.encryptedA = `E(${paillier.a}) = 0x${generateFakeEncryption(paillier.a, 'paillier')}`;
  paillier.encryptedB = `E(${paillier.b}) = 0x${generateFakeEncryption(paillier.b, 'paillier')}`;
  
  // 模拟密文相乘（对应明文相加）
  paillier.ciphertextResult = `E(${paillier.a}) · E(${paillier.b}) = 0x${generateFakeEncryption(paillier.plaintextResult, 'paillier')}`;
  
  paillier.calculated = true;
}

// 生成模拟的加密字符串
function generateFakeEncryption(value, scheme) {
  const chars = '0123456789ABCDEF';
  let result = '';
  
  // 添加一些与原始值相关的字符
  const seed = parseInt(value) % 100;
  for (let i = 0; i < 8; i++) {
    result += chars[(seed + i) % 16];
  }
  
  // 添加随机字符
  const length = scheme === 'rsa' ? 32 : 48; // Paillier 密文通常更长
  for (let i = 0; i < length - 8; i++) {
    result += chars[Math.floor(Math.random() * 16)];
  }
  
  return result;
}

// 初始化误差增长图表
function initErrorChart() {
  if (!errorChart.value) return;
  
  const ctx = errorChart.value.getContext('2d');
  
  // 模拟数据
  const labels = Array.from({ length: 10 }, (_, i) => `乘法 ${i+1}`);
  const bgvData = [0.001, 0.005, 0.02, 0.08, 0.2, 0.5, 0.9, 1.5, 2.2, 3.0];
  const ckksData = [0.001, 0.01, 0.05, 0.15, 0.4, 0.8, 1.5, 2.5, 4.0, 6.0];
  
  // 绘制图表
  if (typeof Chart !== 'undefined') {
    if (chart) {
      chart.destroy();
    }
    
    chart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: labels,
        datasets: [
          {
            label: 'BGV 误差',
            data: bgvData,
            borderColor: '#2962FF',
            backgroundColor: 'rgba(41, 98, 255, 0.1)',
            tension: 0.4
          },
          {
            label: 'CKKS 误差',
            data: ckksData,
            borderColor: '#FF5722',
            backgroundColor: 'rgba(255, 87, 34, 0.1)',
            tension: 0.4
          }
        ]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: {
          y: {
            beginAtZero: true,
            title: {
              display: true,
              text: '相对误差'
            }
          },
          x: {
            title: {
              display: true,
              text: '连续乘法操作'
            }
          }
        }
      }
    });
  } else {
    // 如果Chart.js未加载，绘制简单的图表
    drawSimpleChart(ctx, labels, bgvData, ckksData);
  }
}

// 绘制简单的图表（不依赖Chart.js）
function drawSimpleChart(ctx, labels, bgvData, ckksData) {
  const width = ctx.canvas.width;
  const height = ctx.canvas.height;
  const padding = 40;
  const chartWidth = width - 2 * padding;
  const chartHeight = height - 2 * padding;
  
  // 清除画布
  ctx.clearRect(0, 0, width, height);
  
  // 绘制坐标轴
  ctx.beginPath();
  ctx.moveTo(padding, padding);
  ctx.lineTo(padding, height - padding);
  ctx.lineTo(width - padding, height - padding);
  ctx.strokeStyle = '#666';
  ctx.stroke();
  
  // 绘制BGV数据
  const maxValue = Math.max(...bgvData, ...ckksData);
  drawLine(ctx, bgvData, maxValue, padding, chartWidth, chartHeight, '#2962FF');
  
  // 绘制CKKS数据
  drawLine(ctx, ckksData, maxValue, padding, chartWidth, chartHeight, '#FF5722');
  
  // 绘制图例
  ctx.font = '12px Arial';
  ctx.fillStyle = '#2962FF';
  ctx.fillRect(padding, padding - 20, 15, 10);
  ctx.fillText('BGV 误差', padding + 20, padding - 12);
  
  ctx.fillStyle = '#FF5722';
  ctx.fillRect(padding + 100, padding - 20, 15, 10);
  ctx.fillText('CKKS 误差', padding + 120, padding - 12);
}

// 绘制线条
function drawLine(ctx, data, maxValue, padding, chartWidth, chartHeight, color) {
  const stepX = chartWidth / (data.length - 1);
  
  ctx.beginPath();
  ctx.moveTo(padding, chartHeight + padding - (data[0] / maxValue) * chartHeight);
  
  for (let i = 1; i < data.length; i++) {
    const x = padding + i * stepX;
    const y = chartHeight + padding - (data[i] / maxValue) * chartHeight;
    ctx.lineTo(x, y);
  }
  
  ctx.strokeStyle = color;
  ctx.lineWidth = 2;
  ctx.stroke();
}

// 监听FHE参数变化，更新图表
watch([() => fhe.polyDegree, () => fhe.modulusBits], () => {
  if (sections.bgv_ckks) {
    initErrorChart();
  }
});

// 监听部分展开状态，当BGV/CKKS部分展开时初始化图表
watch(() => sections.bgv_ckks, (newValue) => {
  if (newValue) {
    // 延迟初始化图表，确保DOM已更新
    setTimeout(() => {
      initErrorChart();
    }, 100);
  }
});

onMounted(() => {
  // 尝试加载Chart.js
  if (typeof Chart === 'undefined') {
    const script = document.createElement('script');
    script.src = 'https://cdn.jsdelivr.net/npm/chart.js';
    script.onload = () => {
      if (sections.bgv_ckks) {
        initErrorChart();
      }
    };
    document.head.appendChild(script);
  }
});
</script>

<style scoped>
.algorithms-view {
  max-width: 1000px;
  margin: 0 auto;
  padding: 2rem 1rem;
}

.page-title {
  text-align: center;
  margin-bottom: 1rem;
}

.page-description {
  text-align: center;
  max-width: 800px;
  margin: 0 auto 3rem;
  color: var(--text-secondary);
}

.algorithms-container {
  display: flex;
  flex-direction: column;
  gap: 2rem;
  margin-bottom: 3rem;
}

/* 算法部分样式 */
.algorithm-section {
  background-color: var(--card-bg);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.algorithm-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem;
  cursor: pointer;
  background-color: var(--footer-bg);
  transition: background-color 0.2s;
}

.algorithm-header:hover {
  background-color: var(--hover-bg);
}

.algorithm-header h2 {
  margin: 0;
}

.toggle-icon {
  font-size: 1.2rem;
  color: var(--primary-color);
}

.algorithm-content {
  padding: 1.5rem;
  animation: slideDown 0.3s;
}

.algorithm-description {
  margin-bottom: 2rem;
}

/* 数学公式样式 */
.math-formula {
  background-color: var(--footer-bg);
  padding: 1.5rem;
  border-radius: 6px;
  margin: 1.5rem 0;
}

.formula {
  font-family: 'Roboto Mono', monospace;
  font-size: 1.2rem;
  text-align: center;
  margin: 1rem 0;
  color: var(--primary-color);
}

/* 交互式示例样式 */
.interactive-demo {
  background-color: var(--footer-bg);
  padding: 1.5rem;
  border-radius: 6px;
  margin-bottom: 2rem;
}

.interactive-demo h3 {
  margin-top: 0;
  margin-bottom: 1.5rem;
}

.demo-inputs {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.input-group {
  flex: 1;
  min-width: 150px;
}

.demo-results {
  background-color: var(--bg-color);
  padding: 1.5rem;
  border-radius: 6px;
  animation: fadeIn 0.5s;
}

.result-row {
  display: flex;
  margin-bottom: 1rem;
}

.result-label {
  flex: 1;
  font-weight: 500;
}

.result-value {
  flex: 2;
  font-family: 'Roboto Mono', monospace;
  word-break: break-all;
}

.result-value.encrypted {
  color: var(--primary-color);
  font-size: 0.9rem;
}

.verification-status {
  text-align: center;
  padding: 0.75rem;
  border-radius: 4px;
  font-weight: 500;
  margin-top: 1.5rem;
}

.verification-status.success {
  background-color: rgba(76, 175, 80, 0.1);
  color: var(--success-color);
}

.verification-status.error {
  background-color: rgba(244, 67, 54, 0.1);
  color: var(--error-color);
}

/* 密钥生成流程样式 */
.key-generation {
  margin-bottom: 2rem;
}

.flow-diagram {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.5rem;
}

.flow-step {
  flex: 1;
  min-width: 150px;
  background-color: var(--bg-color);
  padding: 1rem;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.step-number {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background-color: var(--primary-color);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  margin-bottom: 0.75rem;
}

.flow-arrow {
  color: var(--primary-color);
  font-weight: bold;
}

/* BGV/CKKS 部分样式 */
.scheme-comparison {
  display: flex;
  gap: 1.5rem;
  margin: 1.5rem 0;
}

.scheme-card {
  flex: 1;
  background-color: var(--bg-color);
  padding: 1.5rem;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.scheme-card h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: var(--primary-color);
}

.scheme-card p {
  margin-bottom: 0.75rem;
}

/* 参数面板样式 */
.parameter-panel {
  background-color: var(--bg-color);
  padding: 1.5rem;
  border-radius: 6px;
  margin-bottom: 2rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.parameter-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
}

.parameter-group {
  margin-bottom: 1rem;
}

.parameter-group label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
}

.parameter-description {
  font-size: 0.9rem;
  color: var(--text-secondary);
  margin-top: 0.5rem;
}

.range-value {
  text-align: center;
  margin-top: 0.5rem;
  font-weight: 500;
  color: var(--primary-color);
}

/* 误差增长图表样式 */
.error-growth {
  margin-bottom: 2rem;
}

.chart-container {
  background-color: var(--bg-color);
  padding: 1.5rem;
  border-radius: 6px;
  margin: 1.5rem 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  height: 350px;
}

.chart-description {
  font-size: 0.9rem;
  color: var(--text-secondary);
}

/* 算法应用和局限性样式 */
.algorithm-applications,
.algorithm-limitations {
  background-color: var(--bg-color);
  padding: 1.5rem;
  border-radius: 6px;
  margin-top: 1.5rem;
}

.algorithm-applications h3,
.algorithm-limitations h3 {
  margin-top: 0;
  margin-bottom: 1rem;
}

.algorithm-applications ul,
.algorithm-limitations ul {
  padding-left: 1.5rem;
}

.algorithm-applications li,
.algorithm-limitations li {
  margin-bottom: 0.5rem;
}

/* 延伸阅读部分样式 */
.further-reading {
  margin-top: 3rem;
}

.further-reading h2 {
  text-align: center;
  margin-bottom: 2rem;
}

.reading-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

.reading-card {
  background-color: var(--card-bg);
  padding: 1.5rem;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.reading-card h3 {
  margin-top: 0;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border-color);
}

.reading-card ul {
  padding-left: 1.5rem;
}

.reading-card li {
  margin-bottom: 0.75rem;
}

/* 动画 */
@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .scheme-comparison {
    flex-direction: column;
  }
  
  .flow-diagram {
    flex-direction: column;
  }
  
  .flow-arrow {
    transform: rotate(90deg);
    margin: 0.5rem 0;
  }
}
</style>